/**
 * 用于给data中所有的数据添加getter和setter
 * 方便在获取或设置data中的数据的时候，实现一些逻辑
 */
class Observer {
  constructor (data) {
    this.data = data
    this.walk(this.data)
  }

  /***********
   * 核心方法 *
   ***********/

  /**
   * 遍历data中所有数据
   * 添加getter和setter
   */
  walk (data) {
    if (!data || typeof data !== 'object') {
      return
    }

    Object.keys(data).forEach(key => {
      // 给data对象的key设置getter和setter
      this.defineReactive(data, key, data[key])
      // 如果data[key]是一个复杂类型，递归的walk
      this.walk(data[key])
    })
  }

  /**
   * 定义响应式的数据（数据劫持）
   */
  // data中每一个数据都应该维护一个dep对象
  // dep保存了所有订阅了该数据的订阅者
  defineReactive (obj, key, value) {
    let self = this
    let dep = new Dep()
    Object.defineProperty(obj, key, {
      enumerable: true,
      configurable: true,
      get () {
        Dep.target && dep.addSub(Dep.target)
        return value
      },
      set (newValue) {
        if (value === newValue) {
          return
        }
        value = newValue
        // 如果newValue是一个对象 对它尽享劫持
        self.walk(newValue)
        // 发布通知 让所有订阅者更新内容
        dep.notify()
      }
    })
  }
}